import Cookies from 'js-cookie'
class StorageUtils {
    /**
     * 
     * @description 检查本地存储是否存在,是否过期,只负责取数据 
     * @param {String} key 数据的key
     * @param {StorageTypeEnum} storageType 存到哪
     * @param {int} expireTime 本地存储时间
     * @static 
     * @memberof StorageUtils
     */
    static getStorageItem(key, storageType, { expireTime = 0 } = {}) {
        // TODO :: 对key解密
        return new Promise((reslove) => {
            // 配置过期时间
            try {
                let _data = null;
                // 判断存到哪
                switch (storageType) {
                    case StorageTypeEnum.local:
                        _data = localStorage.getItem(key);
                        break;
                    case StorageTypeEnum.session:
                        _data = sessionStorage.getItem(key);
                        break;
                    case StorageTypeEnum.cookie: {
                        const cookieKey = encodeURI(key);
                        _data = decodeURI(Cookies.get(cookieKey));
                        break;
                    }
                    default:
                        _data = localStorage.getItem(key);
                        break;
                }

                let { localData = null, createTime = null } = JSON.parse(_data);
                if (!localData) {
                    // 本地不存在
                    let { error } = new LocalErrorModel("NOTEXIST");
                    return reslove({ localData: error, hasGotItem: false });
                } else {
                    if (expireTime > 0 && Math.abs(createTime - Date.now()) > expireTime) {
                        // 超时
                        let { error } = new LocalErrorModel("EXPIRE");
                        return reslove({ localData: error, hasGotItem: false });
                    } else {
                        return reslove({ localData, hasGotItem: true });
                    }
                }
            } catch (err) {
                // 取出的数据有问题
                let { error } = new LocalErrorModel("DATAERROR");
                return reslove({ localData: error, hasGotItem: false });
            }
        });
    }

    /**
     *
     * @description 检查本地存储是否存在,是否过期,只负责存数据 
     * @static
     * @param {String} key 必传
     * @param {StorageTypeEnum} storageType 必传
     * @param {*} data 必传
     * @returns
     * @memberof StorageUtils
     */
    static setStorageItem(key, storageType, data) {
        // TODO :: 对key加密
        return new Promise((reslove) => {
            try {
                // 加一层方便解析
                const localDataModel = new LocalStorageModel({ localData: data });
                const setLocalData = JSON.stringify(localDataModel);
                // 判断存到哪
                switch (storageType) {
                    case StorageTypeEnum.local:
                        localStorage.setItem(key, setLocalData);
                        break;
                    case StorageTypeEnum.session:
                        sessionStorage.setItem(key, setLocalData);
                        break;
                    case StorageTypeEnum.cookie: {
                        // 用接口命名会有/之类的符号被转义
                        const cookieKey = encodeURI(key);
                        const cookieData = encodeURI(setLocalData);
                        if (cookieData.length > 4000) {
                            // cookie只能存4095个数据
                            let { error } = new LocalErrorModel("COOKIEOVERFLOW");
                            return reslove({ localData: error, hasGotItem: false });
                        }
                        Cookies.set(cookieKey, cookieData);
                        break;
                    }
                    default:
                        sessionStorage.setItem(key, setLocalData);
                        break;
                }
                reslove(true);
            } catch (error) {
                reslove(false);
            }

        })
    }


    /**
     *
     *
     * @static
     * @param {StorageTypeEnum} storageType
     * @memberof StorageUtils
     * @description 清除所有缓存
     */
    static removeAllStorageItems(storageType) {
        return new Promise((reslove, reject) => {
            try {
                switch (storageType) {
                    case StorageTypeEnum.local:
                        localStorage.clear();

                        break;
                    case StorageTypeEnum.session:
                        sessionStorage.clear();
                        break;
                    case StorageTypeEnum.cookie:
                        break;
                    default:
                        sessionStorage.clear();
                        break;
                }
                reslove(true);
            } catch (err) {
                reject(err);
            }
        })
    }

    /**
     *
     *
     * @static
     * @param {StorageTypeEnum} storageType
     * @memberof StorageUtils
     * @description 清除一项缓存
     */
    static removeStorageItem(storageType, key) {
        return new Promise((reslove, reject) => {
            try {
                switch (storageType) {
                    case StorageTypeEnum.local:
                        localStorage.removeItem(key);
                        break;
                    case StorageTypeEnum.session:
                        sessionStorage.removeItem(key);
                        break;
                    case StorageTypeEnum.cookie: {
                        const cookieKey = encodeURI(key);
                        Cookies.remove(cookieKey);
                        break;
                    }
                    default:
                        localStorage.removeItem(key);
                        break;
                }
                reslove(true);
            } catch (err) {
                reject(err);
            }
        })
    }
}


/**
 * @description 本地存储model
 * @description 存localData和createTime
 * @description createTime 默认取当前时间
 * @class LocalStorageModel
 */
class LocalStorageModel {
    constructor({ localData, createTime = Date.now() } = {}) {
        this.localData = localData;
        this.createTime = createTime;
    }
}


/**
 * 
 * @description 本地存储错误信息model
 * @class LocalErrorModel
 */
class LocalErrorModel {
    constructor(type) {
        let errorMessage = {
            NOTEXIST: {
                code: 500,
                msg: "本地没有存储"
            },
            EXPIRE: {
                code: 501,
                msg: "本地存储过期"
            },
            DATAERROR: {
                code: 503,
                msg: "本地数据异常"
            },
            COOKIEOVERFLOW: {
                code: 504,
                msg: "cookie存不下"
            },
            NOTFOUND: {
                code: 404,
                msg: "本地未定义错误类型"
            }
        }
        this.getErrorMsg(type, errorMessage);
    }
    getErrorMsg(type, errorMessage) {
        this.error = errorMessage[type] || errorMessage["NOTFOUND"];
    }
}


/**
 *
 *
 * @class StorageTypeEnum
 * @description 存储类型伪枚举
 */
class StorageTypeEnum {
    static local = "local";
    static session = "session";
    static cookie = "cookie";
}
export default StorageUtils;
export { StorageTypeEnum } 
